home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Tool Chest / Development Kits / MPW etc. / Debuggers / SADE / SADE 1.3.3 / SADE Example Scripts / sc7 < prev   
Encoding:
Text File  |  1991-07-29  |  4.1 KB  |  151 lines  |  [TEXT/sade]

  1. #    Symbolic Application Debugging Environment    1.3 Final
  2. #
  3. #    Copyright Apple Computer, Inc. 1987-1991
  4. #    All rights reserved.
  5.  
  6. ###############################################################################
  7.  
  8.  
  9. define __ROMlo__, __ROMhi__            # ROM boundaries
  10. define __heapLo__, __heapHi__        # heap boundaries
  11. define __stackLo__, __stackHi__        # stack boundaries
  12.  
  13.  
  14. # Inits stuff and makes sure stack is OK before we try to crawl it.
  15. func InitSC7()
  16.     __stackLo__ := A7
  17.     __stackHi__ := CurStackBase
  18.     __heapLo__ := ApplZone
  19.     __heapHi__ := ApplLimit
  20.     __ROMlo__ := RomBase & TargetAddrMask
  21.     __ROMhi__ := __ROMlo__ + $40000    # assume 256K ROM- need a better way!!!
  22.     if (__stackLo__ & 1) or (__stackHi__ & 1) then
  23.         return 0
  24.     end
  25.     if (A7 > __stackHi__) then
  26.         return 0
  27.     end
  28.     return 1
  29. end
  30.  
  31. # Returns 1 if addr is in application heap or ROM.
  32. func IsCodeAddr(addr)
  33.     addr := unsignedlong(addr & TargetAddrMask)
  34.     if (addr >= __heapLo__) and (addr <= __heapHi__) then        # in heap
  35.         return 1
  36.     elseif (addr >= __ROMlo__) and (addr <= __ROMhi__) then        # in ROM
  37.         return 1
  38.     end
  39.     return 0
  40. end
  41.  
  42. # Is addr the return address to somewhere?
  43. # This function checks whether the location immediately before
  44. # addr contains a JSR, BSR, or A-trap, and if so returns the
  45. # address of that instruction.  Otherwise it returns 0.
  46. func ReturnAddress(addr)
  47.     define instr, callAddr
  48.     addr := unsignedlong(addr & TargetAddrMask)
  49.     # check if addr is in an executable region
  50.     if not IsCodeAddr(addr) then
  51.         return 0            # not in heap (or ROM)
  52.     end
  53.     callAddr := unsignedlong(addr - 2)
  54.     if not IsCodeAddr(callAddr) then
  55.         return 0
  56.     end
  57.     instr := ^unsignedword(callAddr)^
  58.     if instr = $6100 then
  59.         return callAddr        # BSR with byte displacement
  60.     elseif (instr & $FFF8) = $4E90 then
  61.         return callAddr        # JSR (An)
  62.     elseif (instr & $F000) = $A000 then
  63.         return callAddr        # A-trap
  64.     end
  65.     callAddr := unsignedlong(addr - 4)
  66.     if not IsCodeAddr(callAddr) then
  67.         return 0
  68.     end
  69.     instr := ^unsignedword(callAddr)^
  70.     if instr = $6100 then
  71.         return callAddr        # BSR with word displacement
  72.     elseif (instr & $FFF8) = $4EA8 then
  73.         return callAddr        # JSR (disp, An)
  74.     elseif (instr & $FFF8) = $4EB0 then
  75.         return callAddr        # JSR (disp, An, Dn)
  76.     elseif instr = $4EBA then
  77.         return callAddr        # JSR (disp, PC)
  78.     elseif instr = $4EBB then
  79.         return callAddr        # JSR (disp, PC, Dn)
  80.     elseif instr = $4EB8 then
  81.         return callAddr        # JSR (xxxx).W
  82.     end
  83.     callAddr := unsignedlong(addr - 6)
  84.     if not IsCodeAddr(callAddr) then
  85.         return 0
  86.     end
  87.     instr := ^unsignedword(callAddr)^
  88.     if instr = $4EB9 then
  89.         return callAddr        # JST (xxxx).L
  90.     end
  91.     return 0                # not a return addr
  92. end
  93.  
  94. # Does addr seem to point to an A6 link value?
  95. # We check that addr is even, within the stack boundaries, and between
  96. # the actual A6 and previous A6 values (or, of course, that it actually
  97. # points to the previous A6!).
  98. func A6Link(addr, prevA6)
  99.     if (addr & 1) or (addr < __stackLo__) or (addr > __stackHi__) then
  100.         return 0
  101.     end
  102.     if (^unsignedlong(addr)^ = prevA6) then
  103.         return 1
  104.     end
  105.     if (addr < A6) or (addr < prevA6) then
  106.         return 0
  107.     end
  108.     return 1
  109. end
  110.  
  111. # Try stack addresses from CurStackBase down to current A7.
  112. # For each that looks like a return address, display it and
  113. # check the preceding value to see if it looks like an A6 link.
  114. proc ShowFrame(prevA6, thisA7)
  115.     define name
  116.     define maybeA6loc := thisA7 - 4    # might be an A6 link value here
  117.     define nextA7 := thisA7 - 2        # check on word boundaries
  118.     define callAddr := ReturnAddress(^unsignedlong(thisA7)^)
  119.     if callAddr <> 0 then
  120.         printf "$%.8X     ", long(thisA7)
  121.         if A6Link(maybeA6loc, prevA6) then
  122.             printf "$%.8X     ", long(maybeA6loc)
  123.             prevA6 := maybeA6loc
  124.         else
  125.             printf "              "
  126.         end
  127.         name := where(callAddr)
  128.         if copy(name, 1, 1) = '$' then
  129.             name := ''
  130.         end
  131.         printf "$%.8X  %s\n", long(callAddr), name
  132.     end
  133.     if nextA7 >= A7 then
  134.         ShowFrame(prevA6, nextA7)
  135.     end
  136. end
  137.  
  138. # The main entry point.
  139. proc StackCrawl7
  140.     CheckNullTarget
  141.     if not InitSC7() then
  142.         alert "Damaged stack:\nA7 must be even and <= CurStackBase."
  143.         abort
  144.     end
  145.     printf "Return addresses on the stack\n"
  146.     printf "Stack Addr    Frame Addr    Caller\n"
  147.     ShowFrame(0, CurStackBase - 4)
  148. end
  149.  
  150. macro sc7    'StackCrawl7'
  151.